"use strict";

require("core-js/modules/es.array.reduce.js");

require("core-js/modules/es.array.reverse.js");

var _dec, _dec2, _dec3, _dec4, _class, _class2, _descriptor, _descriptor2;

function _initializerDefineProperty(target, property, descriptor, context) { if (!descriptor) return; Object.defineProperty(target, property, { enumerable: descriptor.enumerable, configurable: descriptor.configurable, writable: descriptor.writable, value: descriptor.initializer ? descriptor.initializer.call(context) : void 0 }); }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; }

function _initializerWarningHelper(descriptor, context) { throw new Error('Decorating class property failed. Please ensure that ' + 'proposal-class-properties is enabled and runs after the decorators transform.'); }

/* 
学习装饰器语法
*/

/* 
https://caniuse.com/?search=Decorator

*/

/* 
Targtet 就是我们装饰器修饰的这个类 装饰器的底层转换类似如下：

T = T(Person);


*/
function T(prefix) {
  console.log('T call--------------------->');
  return function (v2Prefix) {
    return function (Targtet) {
      /* 可以对这个类进行扩充形成 对象的原型的方法和属性 */
      Targtet.prototype.type = 'human';

      Targtet.prototype.say = function () {
        console.log(prefix + ' say hello ' + v2Prefix);
      };
      /* 扩展静态的属性和方法 */


      Targtet.isType = 'Person Human';

      Targtet.fn = function () {
        console.log('fn call...');
      };
    };
  };
}
/* 装饰器还可以叠加，叠罗汉，汉罗塔，语法是从上到下叠罗汉，执行的时候是从下到上调用。
- https://nestjs.bootcss.com/modules


import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}

底层有点类似：  Person = T1(T('[-_-]')('([+_+])')(Person));
    > https://www.jianshu.com/p/6319f4e5e3b0
*/


function T1(Target) {
  console.log('T1 call--------------------->');

  Target.prototype.run = function () {
    console.log('i can run!!!');
  };
}
/* 
    Reflect
    Proxy

*/

/* Object.defineProperty(p1, 'name', {
    writable: true, // 配置对象  name 是否修改 true 可以 false 不可以 
    enumerable: true, // 配置对象 name 是否 是否被遍历 for in (不支持 for of) [Symbol.iterator]
    configurable: true, // 配置对象 name 是否 可以被删除 delete
}); */

/* 
enumerable 遍历
 */


function enumerable(value) {
  /* 
      target 类
      key 方法名称
      descriptor 方法的属性描述
  */
  return function (target, key, descriptor) {
    descriptor.enumerable = value;
    return descriptor;
  };
}

function writable(value) {
  /* 
      target 类
      key 方法名称
      descriptor 方法的属性描述
  */
  return function (target, key, descriptor) {
    descriptor.writable = value;
    return descriptor;
  };
}

let Person = (_dec = T('[-_-]')('([+_+])'), _dec2 = enumerable(false), _dec3 = writable(true), _dec4 = enumerable(false), T1(_class = _dec(_class = (_class2 = class Person {
  /* name 属性是不可以被修改和枚举（遍历） */
  constructor(name) {
    _initializerDefineProperty(this, "age", _descriptor, this);

    _initializerDefineProperty(this, "name", _descriptor2, this);

    this.name = name;
  }

  sing() {
    console.log('sing...');
  }

}, (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "age", [_dec2], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function initializer() {
    return 12;
  }
}), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "name", [_dec3, _dec4], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function initializer() {
    return '';
  }
})), _class2)) || _class) || _class);
const p1 = new Person('andy');
p1.sing();
console.log(p1.age);
console.log(p1.name);
console.log('遍历对象 for in');

for (let key in p1) {
  console.log(key);
}

p1.name = 'mark';
console.log('p1.name:', p1.name);